home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
DDJ0992.ARJ
/
HRTTEST.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-16
|
6KB
|
253 lines
/*
** hrttest.c - hrtime test program
*/
/*
** Copyright notice begins here:
** Copyright (c) 1991 by Thomas A. Roden
** All Rights Reserved (with one exception).
** The right to freely distribute this source and any executable code
** it creates is granted, provided that this copyright notice is
** included in the source.
**
** It is requested that the author's name (Thomas A. Roden) be included
** in the acknowledgements of any product including this code, but this
** request is in no way legally binding.
** Copyright notice ends here:
*/
#include <stdio.h>
#include <stdlib.h>
typedef unsigned long U32;
/*
** constants for ticklet to second conversions
** ticklet to microsecond: error < 1.3e-07 (one part in seven million)
** max out value 40,904,449
** microsecond to ticklet: error < 1.3e-07 (one part in seven million)
** max out value 48,806,446
** ticklet to millisecond: error < 1.3e-07 (one part in seven million)
** max out value 327,235
** millisecond to ticklet: error < 1.3e-07 (one part in seven million)
** max out value 390,450,852
*/
#define T2USEC_NUMERATOR 88
#define T2USEC_DENOMINATOR 105
#define T2USEC_MAX_IN 48806445
#define USEC2T_NUMERATOR 105
#define USEC2T_DENOMINATOR 88
#define USEC2T_MAX_IN 40904450
#define T2MSEC_NUMERATOR 11
#define T2MSEC_DENOMINATOR 13125
#define T2MSEC_MAX_IN 390451572
#define MSEC2T_NUMERATOR 13125
#define MSEC2T_DENOMINATOR 11
#define MSEC2T_MAX_IN 327235
#define T2USEC(i) (ratio_conversion((i), T2USEC_NUMERATOR, \
T2USEC_DENOMINATOR, T2USEC_MAX_IN))
#define USEC2T(i) (ratio_conversion((i), USEC2T_NUMERATOR, \
USEC2T_DENOMINATOR, USEC2T_MAX_IN))
#define T2MSEC(i) (ratio_conversion((i), T2MSEC_NUMERATOR, \
T2MSEC_DENOMINATOR, T2MSEC_MAX_IN))
#define MSEC2T(i) (ratio_conversion((i), MSEC2T_NUMERATOR, \
MSEC2T_DENOMINATOR, MSEC2T_MAX_IN))
extern U32 far hrtime(void);
extern void far hrt_open(void);
extern void far hrt_close(void);
/*
** ratio_conversion - transform a value from one unit to another
** using a ratio, with as little overflow
** as possible
*/
U32 ratio_conversion(U32 in_value, U32 numerator, U32 denominator,
U32 max_input)
{
U32 retVal;
if(in_value>max_input)
in_value = max_input;
retVal = ((in_value*numerator) + (denominator>>1)) / denominator;
return(retVal);
}
/*
** small_self_time - time a small loop to attempt to generate minimum
** intervals and some larger intervals
*/
void small_self_time(U32 num_tries)
{
U32 last_time;
U32 biggest_time;
U32 smallest_time;
U32 big_this;
U32 big_last;
U32 small_this;
U32 small_last;
U32 i;
hrt_open();
biggest_time = 0;
smallest_time = 0xFFFFFFFF;
big_this = 0;
big_last = 0;
last_time = hrtime();
for(i=0; i<num_tries; i++)
{
U32 this_time;
U32 this_diff;
this_time = hrtime();
this_diff = this_time - last_time;
if(this_diff>biggest_time)
{
biggest_time = this_diff;
big_this = this_time;
big_last = last_time;
}
if(this_diff<smallest_time)
{
smallest_time = this_diff;
small_this = this_time;
small_last = last_time;
}
last_time = this_time;
}
hrt_close();
printf("After %lu tries:\n", num_tries);
printf("Largest interval 0x%lx ticklets, smallest interval 0x%lx ticklets\n",
biggest_time, smallest_time);
printf("Big this: 0x%lx, Big last: 0x%lx\n",
big_this, big_last);
printf("Small this: 0x%lx, Small last: 0x%lx\n",
small_this, small_last);
printf("In microseconds:\n");
printf("Largest interval %ld uSeconds, smallest interval %ld uSeconds\n",
T2USEC(biggest_time), T2USEC(smallest_time));
printf("In milliseconds:\n");
printf("Largest interval %ld milliseconds, smallest interval %ld milliseconds\n",
T2MSEC(biggest_time), T2MSEC(smallest_time));
}
/*
** print_self_time - time a printing loop to attempt to generate
** moderate intervals
*/
void print_self_time(void)
{
U32 last_time;
int i;
/*
** initialize timing system
*/
hrt_open();
last_time = hrtime();
for(i=0; i<10; i++)
{
U32 this_time;
U32 this_diff;
this_time = hrtime();
this_diff = this_time - last_time;
last_time = this_time;
printf("Loop #%d, interval %ld uSeconds\n",
i, T2USEC(this_diff));
}
hrt_close();
}
/*
** print_delay - printing at fixed delays to demonstrate
** interval serviceing
*/
void print_delay(void)
{
U32 last_time;
U32 last_adj_time;
U32 requested_diff;
int i;
/*
** initialize timing system
*/
hrt_open();
/*
** set requested interval at 1,000,000 microseconds (1 second)
*/
requested_diff = USEC2T(1000000);
last_time = hrtime();
last_adj_time = last_time;
for(i=0; i<10; i++)
{
U32 this_time;
U32 this_diff;
do
{
this_time = hrtime();
this_diff = this_time - last_adj_time;
} while(this_diff<requested_diff);
printf("Loop #%d, attempted %ld uSeconds, achieved %ld uSeconds\n",
i, T2USEC(requested_diff), T2USEC(this_time-last_time));
/*
** calculating last_adj_time instead of using last_time gives longer
** term stability. otherwise overshoots accumulate.
*/
last_time = this_time;
last_adj_time += requested_diff;
}
hrt_close();
}
int main(int argc, char *argv[])
{
U32 num_tries;
int test_mask;
test_mask = 0x07;
num_tries = 1000;
if(3==argc)
{
test_mask = (int)(strtoul(argv[1], NULL, 0));
num_tries = strtoul(argv[2], NULL, 0);
}
else if(2==argc)
{
test_mask = (int)(strtoul(argv[1], NULL, 0));
}
else if(1!=argc)
printf("<usage>: hrttest [test_mask] [num_tries]\n");
if(0!=(test_mask&0x01))
small_self_time(num_tries);
if(0!=(test_mask&0x02))
print_self_time();
if(0!=(test_mask&0x04))
print_delay();
return(0);
}